/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * http//www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is ART Ontology API.
 *
 * The Initial Developer of the Original Code is University of Roma Tor Vergata.
 * Portions created by University of Roma Tor Vergata are Copyright (C) 2007.
 * All Rights Reserved.
 *
 * ART Ontology API was developed by the Artificial Intelligence Research Group
 * (art.uniroma2.it) at the University of Roma Tor Vergata
 * Current information about the ART Ontology API can be obtained at 
 * http//art.uniroma2.it/owlart
 *
 */

/*
 * Contributor(s): Armando Stellato stellato@info.uniroma2.it
 */
package it.uniroma2.art.owlart.models;

import it.uniroma2.art.owlart.exceptions.ModelAccessException;
import it.uniroma2.art.owlart.exceptions.ModelUpdateException;
import it.uniroma2.art.owlart.model.ARTBNode;
import it.uniroma2.art.owlart.model.ARTLiteral;
import it.uniroma2.art.owlart.model.ARTResource;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.navigation.ARTResourceIterator;

/**
 * Extension to SKOS Interface thought for SKOS-XL compliant models
 * 
 * @author Armando Stellato &lt;stellato@info.uniroma2.it&gt;
 * 
 */
public interface SKOSXLModel extends SKOSModel {

	// ************************
	// XLABEL INNER MANAGEMENT
	// ************************

	// access

	/**
	 * gets the literalform associated to XLabel <code>xLabel</code>
	 * 
	 * @param xLabel
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTLiteral getLiteralForm(ARTResource xLabel, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * since <code>skosxl:labelRelation</code> property represents an extension point and is not thought to be
	 * instantiated its way, if available a reasoner is set by default
	 * 
	 * @param xLabel
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTResourceIterator getRelatedLabels(ARTResource xLabel, ARTResource... graphs)
			throws ModelAccessException;

	// write

	/**
	 * creates a skosxl:Label resource and attaches a literalform to it
	 * 
	 * @param xLabelURI
	 * @param literalForm
	 * @param graphs
	 * @return the created XLabel
	 * @throws ModelUpdateException
	 */
	public abstract ARTURIResource addXLabel(String xLabelURI, ARTLiteral literalForm, ARTResource... graphs)
			throws ModelUpdateException;

	/**
	 * creates a skosxl:Label resource and attaches a literalform to it created from a string label and the
	 * language for it
	 * 
	 * @param xLabelURI
	 * @param literalForm
	 * @param language
	 * @return the created XLabel
	 * @throws ModelUpdateException
	 */
	public abstract ARTURIResource addXLabel(String xLabelURI, String literalForm, String language,
			ARTResource... graphs) throws ModelUpdateException;

	// Note: it is not possible to add a literal form, it is built together with the Label, so the existing
	// one can only be changed (we have to include the removal of previous lexicalform in the
	// changeLiteralForm implementation)

	/**
	 * changes the literal form of the given <code>xLabel</code> according to given arguments
	 * 
	 * @param xLabel
	 * @param literalForm
	 * @throws ModelUpdateException
	 */
	public abstract void changeLiteralForm(ARTResource xLabel, ARTLiteral literalForm, ARTResource... graphs)
			throws ModelUpdateException;

	/**
	 * changes the literal form of the given <code>xLabel</code> according to given arguments
	 * 
	 * @param xLabel
	 * @param literalForm
	 * @param language
	 * @throws ModelUpdateException
	 */
	public abstract void changeLiteralForm(ARTResource xLabel, String literalForm, String language,
			ARTResource... graphs) throws ModelUpdateException;

	// remove

	// Note: it is not possible to remove the literal form, only to change it or to delete the whole xLabel

	/**
	 * deletes the xLabel, and any incoming/outcoming triple related to it. Use only in case of a standard
	 * usage of XLabels. If there is any other additional information about the label which is only used to
	 * describe it and which consists of more than a simple ingoing/outgoing triple, then it should be deleted
	 * explicitly before the label, to avoid dangling triples left in the model
	 * 
	 * @param xLabel
	 * @throws ModelUpdateException
	 */
	public abstract void deleteXLabel(ARTResource xLabel, ARTResource... graphs) throws ModelUpdateException;

	// ************************
	// XLABEL OUTER MANAGEMENT
	// ************************

	// access

	/**
	 * returns the preferred XLabel for concept <code>skosConcept</code> with language given by
	 * <code>languageTag</code>
	 * 
	 * @param skosConcept
	 * @param languageTag
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTResource getPrefXLabel(ARTURIResource skosConcept, String languageTag,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * returns the preferred XLabels (in all available languages) for concept <code>skosConcept</code><br/>
	 * SKOS requires that only one preferred label value is provided for a single concept for each language
	 * 
	 * @param skosConcept
	 * @param graphs
	 * @return
	 * @throws ModelAccessException 
	 */
	public abstract ARTResourceIterator listPrefXLabels(ARTURIResource skosConcept, ARTResource... graphs) throws ModelAccessException;

	/**
	 * list all Alternative XLabels for concept <code>skosConcept</code> with language given by
	 * <code>languageTag</code>
	 * 
	 * @param skosConcept
	 * @param languageTag
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTResourceIterator listAltXLabels(ARTURIResource skosConcept, String languageTag,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * list all Alternative XLabels for concept <code>skosConcept</code>
	 * 
	 * @param skosConcept
	 * @param graphs
	 * @return
	 * @throws ModelAccessException
	 */
	public abstract ARTResourceIterator listAltXLabels(ARTURIResource skosConcept, ARTResource... graphs)
			throws ModelAccessException;

	/**
	 * list all Hidden XLabels for concept <code>skosConcept</code> with language given by
	 * <code>languageTag</code>
	 * 
	 * @param skosConcept
	 * @param languageTag
	 * @param graphs
	 * @return
	 * @throws ModelAccessException 
	 */
	public abstract ARTResourceIterator listHiddenXLabels(ARTURIResource skosConcept, String languageTag,
			ARTResource... graphs) throws ModelAccessException;

	/**
	 * list all Hidden XLabels for concept <code>skosConcept</code>
	 * 
	 * @param skosConcept
	 * @param graphs
	 * @return
	 * @throws ModelAccessException 
	 */
	public abstract ARTResourceIterator listHiddenXLabels(ARTURIResource skosConcept,
			ARTResource... graphs) throws ModelAccessException;

	// write

	/**
	 * sets the preferred label for concept <code>skosConcept</code><br/>
	 * 
	 * @param skosConcept
	 * @param xlabel
	 * @param graphs
	 * @param delete
	 *            if <code>true</code> previous xlabel is deleted as for
	 *            {@link #deleteXLabel(ARTResource, ARTResource...)}
	 * @return
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void setPrefXLabel(ARTURIResource skosConcept, ARTResource xlabel, boolean delete,
			ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	/**
	 * as for {@link #setPrefXLabel(ARTURIResource, ARTResource, boolean, ARTResource...)} with delete=true
	 * 
	 * @param skosConcept
	 * @param xlabel
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void setPrefXLabel(ARTURIResource skosConcept, ARTResource xlabel, ARTResource... graphs)
			throws ModelAccessException, ModelUpdateException;

	/**
	 * sets the preferred label for concept <code>skosConcept</code> by creating it from passed arguments
	 * 
	 * @param skosConcept
	 * @param literalform
	 * @param delete
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void setPrefXLabel(ARTURIResource skosConcept, ARTLiteral literalform, boolean delete,
			ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	/**
	 * as for {@link #setPrefXLabel(ARTURIResource, ARTLiteral, boolean, ARTResource...)} with delete=true
	 * 
	 * @param skosConcept
	 * @param literalform
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void setPrefXLabel(ARTURIResource skosConcept, ARTLiteral literalform,
			ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	/**
	 * sets the preferred label for concept <code>skosConcept</code> by creating it from passed arguments
	 * 
	 * @param skosConcept
	 * @param literalform
	 * @param language
	 * @param delete
	 *            if <code>true</code> previous xlabel is deleted as for
	 *            {@link #deleteXLabel(ARTResource, ARTResource...)}
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void setPrefXLabel(ARTURIResource skosConcept, String literalform, String language,
			boolean delete, ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	/**
	 * as for {@link #setPrefXLabel(ARTURIResource, String, String, boolean, ARTResource...)} with delete=true
	 * 
	 * @param skosConcept
	 * @param literalform
	 * @param language
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void setPrefXLabel(ARTURIResource skosConcept, String literalform, String language,
			ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	/**
	 * adds an alternative xLabel to <code>skosConcept</code><br/>
	 * 
	 * @param skosConcept
	 * @param xlabel
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void addAltXLabel(ARTURIResource skosConcept, ARTResource xlabel, ARTResource... graphs)
			throws ModelAccessException, ModelUpdateException;

	/**
	 * adds an alternative xLabel to <code>skosConcept</code> by constructing it from its plain literalform<br/>
	 * the xlabel will be created as a {@link ARTBNode} and linked to <code>skosConcept</code>
	 * 
	 * @param skosConcept
	 * @param literalform
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void addAltXLabel(ARTURIResource skosConcept, ARTLiteral literalform,
			ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	/**
	 * adds an alternative xLabel to <code>skosConcept</code> by constructing it from its plain string
	 * descriptor and language tag<br/>
	 * 
	 * @param skosConcept
	 * @param literalform
	 * @param language
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void addAltXLabel(ARTURIResource skosConcept, String literalform, String language,
			ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	/**
	 * adds an hidden xLabel to <code>skosConcept</code><br/>
	 * 
	 * @param skosConcept
	 * @param xlabel
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void addHiddenXLabel(ARTURIResource skosConcept, ARTResource xlabel,
			ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	/**
	 * adds an hidden xLabel to <code>skosConcept</code> by constructing it from its plain literalform<br/>
	 * 
	 * @param skosConcept
	 * @param literalform
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void addHiddenXLabel(ARTURIResource skosConcept, ARTLiteral literalform,
			ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	/**
	 * adds an hidden xLabel to <code>skosConcept</code> by constructing it from its plain string descriptor
	 * and language tag<br/>
	 * 
	 * @param skosConcept
	 * @param literalform
	 * @param language
	 * @param graphs
	 * @throws ModelAccessException
	 * @throws ModelUpdateException
	 */
	public abstract void addHiddenXLabel(ARTURIResource skosConcept, String literalform, String language,
			ARTResource... graphs) throws ModelAccessException, ModelUpdateException;

	// remove

	/**
	 * simply deletes any triple linking given <code>skosConcept</code> and <code>xLabel</code><br/>
	 * The xLabel definition, its lexical form and any other relationship with other resources is not removed
	 * from the model<br/>
	 * The reason for the need to specify the skosConcept is that we do not make any assumption on the use of
	 * xlabels in the managed vocabulary. They could be single-meaning linguistic entities attached to single
	 * concepts denoting that meaning, as well as polysemic linguistic expressions attached to more concepts.
	 * For this reason, specifying the concept to which they are bound avoids any ambiguity on this matter.
	 * 
	 * @param skosConcept
	 * @param xLabel
	 * @throws ModelUpdateException
	 */
	public abstract void detachXLabel(ARTResource skosConcept, ARTResource xLabel, ARTResource... graphs)
			throws ModelUpdateException;

}